package edu.fiu.cs.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import Network.Node;

/**
 * @author Chunqiu Zeng
 *
 */
public class NodeSearcher {
	
	/**
	 * @param nodes
	 * @param attribute
	 * @param criteria
	 * @param value
	 * @return
	 */
	public static List<Node> searchNodes(HashMap<String, Node> nodes,
			String attribute[], String criteria[], String value[]) {
		ArrayList<Node> retNodes = new ArrayList<Node>();
		assert (attribute != null && criteria != null && value != null);

		Iterator<String> iter = nodes.keySet().iterator();
		while (iter.hasNext()) {
			Node node = nodes.get(iter.next());
			if (filter(node, attribute, criteria, value)) {
				retNodes.add(node);
			}
		}

		return retNodes;
	}

	/**
	 * @param node
	 * @param attribute
	 * @param criteria
	 * @param value
	 * @return
	 */
	public static boolean filter(Node node, String attribute[],
			String criteria[], String value[]) {
		int len = attribute.length;
                boolean meetAllCriteria = false;
		for (int i = 0; i < len; i++) {
                       /* System.out.println("#1 " +" attribName: "+attribute[i] +" criteria: "+ criteria[i]
                                +" value: "+value[i]);*/
                    
			if ("ipAddress".equalsIgnoreCase(attribute[i])) {
				if (!filtIPAddress(node.getiPAddress(), criteria[i], value[i])) {
					return false;
				}
			} else if ("numOfInflows".equalsIgnoreCase(attribute[i])) {
				if (!filterNumeric(node.getNumOfInflow(), criteria[i],
						Integer.parseInt(value[i]))) {
					return false;
				}
			} else if ("numOfOutflows".equalsIgnoreCase(attribute[i])) {
				if (!filterNumeric(node.getNumOfOutflow(), criteria[i],
						Integer.parseInt(value[i]))) {
					return false;
				}
			} else if ("bytesSent".equalsIgnoreCase(attribute[i])) {
				if (!filterNumeric(node.getBytesSent(), criteria[i],
						Integer.parseInt(value[i]))) {
					return false;
				}
			} else if ("bytesReceived".equalsIgnoreCase(attribute[i])) {
				if (!filterNumeric(node.getBytesReceived(), criteria[i],
						Integer.parseInt(value[i]))) {
					return false;
				}
			} else {
				return false;
			}
		}
                
		return true;
	}

	/**
	 * @param ip
	 * @param criteria
	 * @param v
	 * @return
	 */
	public static boolean filtIPAddress(String ip, String criteria, String v) {
		if (criteria.equals("=")) {
			return ip.equals(v);
		}
		int r = ip.compareTo(v);
		if (criteria.equals("<") && r < 0)
			return true;
		if (criteria.equals(">") && r > 0)
			return true;
		if (criteria.equals("<=") && r <= 0)
			return true;
		if (criteria.equals(">=") && r >= 0)
			return true;
		return false;
	}

	/**
	 * @param t
	 * @param criteria
	 * @param v
	 * @return
	 */
	public static boolean filterNumeric(int t, String criteria, int v) {
		if (criteria.equals("=")) {
			return t == v;
		}

		if (criteria.equals("<"))
			return t < v;
		if (criteria.equals(">"))
			return t > v;
		if (criteria.equals("<="))
			return t <= v;
		if (criteria.equals(">="))
			return t >= v;
		return false;
	}
	
	/**
	 * @param args
	 */
	public static void main(String args[]){
		Node node1= new Node();
		node1.setiPAddress("10.0.0.1");
		node1.setBytesReceived(1);
		node1.setBytesSent(2);
		node1.setNumOfInflow(3);
		node1.setNumOfOutflow(4);
		HashMap<String,Node> map = new HashMap<String,Node >();
		map.put(node1.getiPAddress(), node1);
		String attribute[] = {"ipAddress", "numOfIn"};
		String criteria[] = {"<="};
		String value[]={"10.0.0.1"};
		List<Node> ret = searchNodes(map,attribute,criteria,value);
		for(Node r:ret){
			System.out.println(r.getiPAddress());
		}
		
	}
}
